#ifndef SHARED_MEMORY_H
#define SHARED_MEMORY_H

#include <sys/shm.h>

namespace shared_memory
{
enum AccessMode
{
    ReadOnly = 0,
    ReadWrite
};
enum SharedMemoryError
{
    NoError,
    PermissionDenied,
    InvalidSize,
    KeyError,
    AlreadyExists,
    NotFound,
    LockError,
    OutOfResources,
    UnknownError
};
}

namespace shared_memory
{
/**
 * 共享内存附加类
 * @author: haitao.lin
 */
template<class T>
class SharedMemory
{
public:
    explicit SharedMemory();
    explicit SharedMemory(int key);
    explicit SharedMemory(const std::string &path);
    ~SharedMemory();

    /**
     * 设置共享内存的key，key必须大于0，且不能重复
     */
    void setKey(int key);

    /**
     * 通过目录/文件路径，设置共享内存的key，目录/文件必须存在，且后续不会改变，否则生成key会不一致
     */
    void setKey(const std::string &path);

    /**
     * 创建共享内存段，size表示内存段大小，mode表示读写权限
     */
    bool create(int size, AccessMode mode = ReadWrite);

    /**
     * 返回附加（调用过attach）的共享内存段大小，如果没有附加，则返回0
     */
    int size() const;

    /**
     * 尝试将进程附加到共享内存段
     */
    bool attach(AccessMode mode = ReadWrite);
    bool isAttached() const;

    /**
     * 从共享内存段中分离进程
     */
    bool detach();

    /**
     * 返回共享内存段的数据指针
     */
    T *data();

    /**
     * 返回最后一次的错误信息
     */
    SharedMemoryError error() const;
    std::string errorString() const;

private:
    key_t m_key{-1};
    int m_shm_id{-1};
    void *m_memory{nullptr};

    SharedMemoryError m_error;
    std::string m_errorString;
    int m_size;
};

}

#include "SharedMemory.inl"

#endif //SHARED_MEMORY_H
